package com.example.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import javax.servlet.ServletOutputStream;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import static org.apache.poi.hssf.record.ExtendedFormatRecord.CENTER;

/**
 * Execl工具类
 * 
 * <pre>
 * 支持.xls 和 .xlsx 后缀名的 Excel文件,本工具类针对第一行为表头的Excel文件. xls默认导出最大行数限制为5万
 * xlsx默认导出最大行数限制为100万
 * </p>
 */
public class ExcelUtil {
	// xls导出行数区间 0-65535
	private static Integer MAX_ROW_XLS = 50000;
	// xlsx导出行数区间 0-1048576
	private static Integer MAX_ROW_XLSX = 1000000;
	//SXSSFWorkbook 输出缓冲
	private static Integer rowAccessWindowSize = 1000;
	// 后缀名
	public final static String XLS = "xls";
	public final static String XLSX = "xlsx";
	//行号
	private final static String DATA_NUMBER = "$DataNumber"; 
	
	//数字格式化,格式化后的数字将变为字符串
	private final static DecimalFormat NUMBER_DATA_FORMAT = new DecimalFormat("#"); 
	
	// 获取每个工作表导出的最大行数
	public static Integer getMaxRoW(String excelExtName) throws Exception {
		if (excelExtName.equals(XLS)) {
			return MAX_ROW_XLS;
		} else if (excelExtName.equals(XLSX)) {
			return MAX_ROW_XLSX;
		} else {
			throw new Exception("excel文件后缀名错误！");
		}

	}

	// 设置每个工作表导出的最大行数
	public static void setMaxRoW(String excelExtName, Integer maxRow) throws Exception {
		if (excelExtName.equals(XLS)) {
			MAX_ROW_XLS = maxRow;
		} else if (excelExtName.equals(XLSX)) {
			MAX_ROW_XLSX = maxRow;
		} else {
			throw new Exception("excel文件后缀名错误！");
		}

	}

	/**
	 * 获取Excel文件里面所有工作表的内容，只支持有表头的工作表结构，第一行为Key,列名如若出现重复,将导致数据出错,特别注意空字符串表头
	 * 导入时，我们不能知道该字段想表达的是一个数字信息还是一个编号信息，所以请将不是数字意义的字段在Excel中设置为"文本"
	 * <pre>
	 * 支持的参数形式：
	 * 1.本地读取：filePathOrFileName = 文件路径，inputStream = null;
	 * 2.网络传输：filePathOrFileName = 文件路径或者文件名，inputStream = 文件输入流  (表单类型为MultipleData)
	 * </pre>
	 * 
	 * @param filePathOrFileName
	 *            文件路径或文件名：构建流，确认文件类性
	 * @param inputStream
	 * 			 文件输入流
	 * @param columnNameMapLists
	 *            表头映射映射关系列表,用于替换Excel表中的Key值,为null时不启用该项
	 * @return
	 * @throws Exception
	 */
	public static List<List<Map<String, Object>>> getExcelContent(String filePathOrFileName,InputStream inputStream ) throws Exception {		
		String fileType = filePathOrFileName.substring(filePathOrFileName.lastIndexOf(".") + 1, filePathOrFileName.length());
		InputStream is = null;
		Workbook workBook = null;		
		try {				
			if (null==inputStream) {
				is = new FileInputStream(filePathOrFileName);
			}else{
				is= inputStream;
			}
			
			if (fileType.equals(XLS)) {
				workBook = new HSSFWorkbook(is);
			} else if (fileType.equals(XLSX)) {
				workBook = new XSSFWorkbook(is);
			} else {
				throw new Exception("excel文件后缀名错误！");
			}		
			List<List<Map<String, Object>>> result = new ArrayList<List<Map<String, Object>>>();// 对应excel文件

			int sheetSize = workBook.getNumberOfSheets();
			for (int i = 0; i < sheetSize; i++) {// 遍历sheet页
				Sheet sheet = workBook.getSheetAt(i);
				List<Map<String, Object>> sheetList = new ArrayList<Map<String, Object>>();// 对应sheet页

				List<String> titles = new ArrayList<String>();// 放置所有的标题

				int rowSize = sheet.getLastRowNum() + 1;
				for (int j = 0; j < rowSize; j++) {// 遍历行				
					Row row = sheet.getRow(j);  //行对象			
					Map<String, Object> rowMap = new LinkedHashMap<String, Object>();// 对应一行数据			
					rowMap.put(DATA_NUMBER, Integer.valueOf(j));  //添加行号			
					if (row == null) {// 略过空行的内容设置
//						sheetList.add(rowMap);  //将空行的行号记录纳入数据List中
						continue;
					}
					int cellSize = row.getLastCellNum();// 行中有多少个单元格，也就是有多少列
					if (j == 0) {// 第一行是标题行
						for (int k = 0; k < cellSize; k++) {
							Cell cell = row.getCell(k);
							titles.add((null != cell) ? cell.toString() : "");
						}
					} else {// 其他行是数据行					
						for (int k = 0; k < titles.size(); k++) {
							Cell cell = row.getCell(k);
							String key = titles.get(k);
							Object value = null;
							if (cell != null) {
								//value = cell.toString();
								value=getValueFromExcel(cell);
							}
							rowMap.put(key, value);
						}
						sheetList.add(rowMap);
					}
				}
				result.add(sheetList);
			}
			return result;
		} catch (FileNotFoundException e) {
			throw e;
		} finally {

			if (is != null) {
				workBook.close();
				is.close();
			}

		}
	}

	/**
	 * 在控制体打印Excel表格的内容
	 * 
	 * <pre>
	 * 支持的参数形式：
	 * 1.本地读取：filePathOrFileName = 文件路径，inputStream = null;
	 * 2.网络传输：filePathOrFileName = 文件路径或者文件名，inputStream = 文件输入流   (表单类型为MultipleData)
	 * </pre>
	 * @param filePathOrFileName
	 *            文件路径或文件名：构建流，确认文件类性
	 * @param inputStream
	 * 			 文件输入流
	 * @param columnNameMapLists
	 *            表头映射映射关系列表,用于替换Excel表中的Key值,为null时不启用该项
	 * 
	 * @throws Exception
	 */
	public static void showExcelContent(String filePathOrFileName ,InputStream inputStream) throws Exception {

		int i = 0;
		List<List<Map<String, Object>>>  list;
		if (null==inputStream) {
			list= getExcelContent(filePathOrFileName,null);		
		}else{
			list= getExcelContent(filePathOrFileName,inputStream);		
		}
		for (List<Map<String, Object>> Content : list) {
			System.out.println("Sheet" + ++i);
			for (Map<String, Object> row : Content) {
				System.out.println(row);
			}
		}
	}

	/**
	 * 导出Excel表格 old;
	 * 
	 * @deprecated 此方法不推荐使用,请使用低内存消耗的缓冲输出方法exportExcelForHugeData()
	 * 
	 * @param os
	 *            输出流(默认为FileOutPutStream)
	 * @param outputPath
	 *            本地文件输出路径(默认位置为项目根目录下的Excel文件夹里,如果输出流为ServletOutputStream,
	 *            填null)
	 * @param fileName
	 *            文件名(默认为UUID)，直接IO流传输时填null
	 * @param excelExtName
	 *            Excel文件扩展名("xls"或者"xlsx")，必填
	 * @param sheetNames
	 *            (工作表名列表)
	 * @param columnNameMapLists
	 *            表头映射映射关系列表，决定了列的先后顺序及对数据集的过滤，输出到工作表的列数量以这个的Size为准,必填
	 * @param contentLists
	 *            工作表内容，(JavaBean 或者 Map )
	 * @throws Exception 
	 */
	public static <T> void exportExcel(OutputStream os, String outputPath, String fileName, String excelExtName,
			List<String> sheetNames, List<LinkedHashMap<String, String>> columnNameMapLists, List<List<T>> contentLists)
			throws Exception {

		if (null == columnNameMapLists || 0 == columnNameMapLists.size()) {
			throw new Exception("存在表头映射关系为NULL，请给出有效表头映射关系！");
		} else {
			for (LinkedHashMap<String, String> columnNameMap : columnNameMapLists) {
				if (null == columnNameMap) {
					throw new Exception("存在表头映射关系为NULL，请给出有效表头映射关系！");
				}
			}
		}

		// 设置工作簿参数
		Workbook workBook = null;

		// 单元格样式
		CellStyle cellStyle = null;

		// ---制定Excel---

		// 文件根目录路径为空时，指定为当前根目录下的dir文件夹里
		if (null == outputPath || "".equals(outputPath)) {
			String path = "./Excel";
			File dir = new File(path);
//			System.out.println(dir.getAbsolutePath());
			if (!dir.exists()) {
				dir.mkdirs();
			}
			outputPath = path;
		}
		// 文件名为空时，使用随机文件名
		if (null == fileName || "".equals(fileName)) {
			UUID uuid = UUID.randomUUID();
			fileName = uuid.toString();
			// System.out.println(fileName);
		}

		// 声明文件
		File file = null;
		// 声明输出流
		OutputStream outputStream = null;

		// 流不为null时使用外部流
		if (null != os && os instanceof ServletOutputStream) {
			outputStream = os;
		} else {
			// 建立文件
			file = new File("" + outputPath + "/" + fileName + "." + excelExtName);
			// System.out.println(file.getCanonicalPath());
			// 建立输出流
			outputStream = new FileOutputStream(file);
		}

		// 建立对应后缀名的工作表
//		boolean isXls;
		try {
			if (XLS.equals(excelExtName)) {
				workBook = new HSSFWorkbook();
//				isXls = true;
			} else if (XLSX.equals(excelExtName)) {
				workBook = new XSSFWorkbook();
//				isXls = false;
			} else {
				throw new Exception("excel文件后缀名错误！");
			}
			// 设置水平居中和垂直居中
			cellStyle = workBook.createCellStyle();
//			if (isXls) {
//				cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
//				cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
//			} else {
//				cellStyle.setAlignment(XSSFCellStyle.ALIGN_CENTER);
//				cellStyle.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
//			}
			cellStyle = workBook.createCellStyle();
			// 单元格水平居中
			cellStyle.setAlignment(CENTER);
			// 单元格垂直居中
			cellStyle.setVerticalAlignment(CENTER);
		

			// 工作表名
			for (int i = 0; i < columnNameMapLists.size(); i++) {
				// 设置工作表命名
				Sheet sheet = workBook
						.createSheet(((null != sheetNames && 0 < sheetNames.size() && !"".equals(sheetNames.get(i)))
								? sheetNames.get(i) : "Sheet" + (i + 1)));

				// Excel坐标
				int x = 0;
				int y = 0;

				// 设置工作表列名对应的成员变量名列表
				List<String> fieldNameList = null;
				// 列名不为空
				if (null != columnNameMapLists.get(i)) {

					// 获取工作表列名
					Map<String, String> columnNameMap = columnNameMapLists.get(i);
					Set<String> fieldNames = columnNameMap.keySet();

					// 设置工作表列名
					fieldNameList = new LinkedList<String>();
					Row row = sheet.createRow(y);
					for (String fieldName : fieldNames) {
						// 设置列名
						Cell cell = row.createCell(x);
						cell.setCellStyle(setColumnNameStyle(workBook, excelExtName));
						cell.setCellValue(columnNameMap.get(fieldName));
						//设置列宽
						setColumnWidth(sheet, x);
						fieldNameList.add(fieldName);
						x++;
					}
					y++;

				}

				// 内容不为空
				if (null != contentLists && i < contentLists.size()) {

					// 设置内容
					for (T object : contentLists.get(i)) {
						// 忽略空对象
						if (null != object) {
							x = 0;
							Row row = sheet.createRow(y);

							for (String fieldName : fieldNameList) {
								Object attribute = null;

								if (object instanceof Map) {
									// 获取Map中的值
									attribute = ((Map<?, ?>) object).get(fieldName);
								} else {
									// 获取对象中的值
									Field field = object.getClass().getDeclaredField(fieldName);
									field.setAccessible(true);
									attribute = field.get(object);
								}

								Object value = getFormatValue(object, attribute);
								Cell cell = row.createCell(x);
								cell.setCellStyle(cellStyle);

								if (value instanceof String) {
									cell.setCellValue((String) value);
								} else if (value instanceof Double) {
									cell.setCellValue((Double) value);
								}
								x++;
							}

						}
						y++;
						// 导出上限
						if (y > ExcelUtil.getMaxRoW(excelExtName)) {
							break;
						}
					}

				}

			}

			// 写出Excel
			workBook.write(outputStream);
			// 关闭输出流
			if (null != outputStream) {
				outputStream.flush();
				outputStream.close();
			}
		} catch (Exception e) {
			e.printStackTrace();

			// 关闭输出流
			if (null != outputStream) {
				outputStream.flush();
				outputStream.close();
				
			}
			if (!(os instanceof ServletOutputStream)) {
				// 删除文件
				if (null != file) {
					file.delete();
				}
			}
			throw new Exception(e);
		}
	}


	/**
	 * 导出Excel表格大数据量使用，后缀名：xlsx;
	 * 
	 * @param os
	 *            输出流(默认为FileOutPutStream)
	 * @param outputPath
	 *            本地文件输出路径(默认位置为项目根目录下的Excel文件夹里,如果输出流为ServletOutputStream,
	 *            填null)
	 * @param fileName
	 *            文件名(默认为UUID),直接IO流形式传输时填null
	 * @param columnNameMapLists
	 *            表头映射映射关系列表，决定了列的先后顺序及对数据集的过滤，输出到工作表的列数量以这个的Size为准,必填
	 * @param contentLists
	 *            工作表内容，(JavaBean 或者 Map )
	 * @return  文件绝对路径,文件不存在时返回 null
	 * @throws Exception
	 */
	public static <T> String exportExcelForHugeData(OutputStream os, String outputPath, String fileName, 
			 List<LinkedHashMap<String, String>> columnNameMapLists, List<List<T>> contentLists)
			throws Exception {
		//后缀名
		String excelExtName = XLSX;
		//文件路径
		String  excelPath=null;
		
		if (null == columnNameMapLists || 0 == columnNameMapLists.size()) {
			throw new Exception("存在表头映射关系为NULL，请给出有效表头映射关系！");
		} else {
			for (LinkedHashMap<String, String> columnNameMap : columnNameMapLists) {
				if (null == columnNameMap) {
					throw new Exception("存在表头映射关系为NULL，请给出有效表头映射关系！");
				}
			}
		}

		// 设置工作簿参数
		SXSSFWorkbook sxssfWorkbook = null;

		// 单元格样式
		CellStyle cellStyle = null;

		// ---制定Excel---

		// 文件根目录路径为空时，指定为当前根目录下的dir文件夹里
		if (null == outputPath || "".equals(outputPath)) {
			String path = "./Excel";
			File dir = new File(path);
//			System.out.println(dir.getAbsolutePath());
			if (!dir.exists()) {
				dir.mkdirs();
			}
			outputPath = path;
		}
		// 文件名为空时，使用随机文件名
		if (null == fileName || "".equals(fileName)) {
			UUID uuid = UUID.randomUUID();
			fileName = uuid.toString();
			// System.out.println(fileName);
		}
		// 声明文件
		File file = null;
		// 声明输出流
		OutputStream outputStream = null;
		
		
		// 建立文件
		String path = "" + outputPath + "\\" + fileName + "." + excelExtName;
		file = new File(path);
		//获取文件全路径
		excelPath = file.getCanonicalPath();
//		System.out.println(file.getCanonicalPath());
//		// 建立输出流
//		outputStream = new FileOutputStream(file);
		
		// 流不为null时使用外部流
		if (null != os && os instanceof ServletOutputStream) {
			outputStream = os;
		} else {
			// 建立文件
			file = new File("" + outputPath + "/" + fileName + "." + excelExtName);
			// System.out.println(file.getCanonicalPath());
			// 建立输出流
			outputStream = new FileOutputStream(file);
		}

		// 建立.xlsx工作表
		try {
			//创建工作簿
			sxssfWorkbook = new SXSSFWorkbook(rowAccessWindowSize);
			
			
			// 设置水平居中和垂直居中
			cellStyle = sxssfWorkbook.createCellStyle();
			// 单元格水平居中
			cellStyle.setAlignment(CENTER);
			// 单元格垂直居中
			cellStyle.setVerticalAlignment(CENTER);
			

			// 工作表名
			for (int i = 0; i < columnNameMapLists.size(); i++) {
				// 设置工作表命名
				Sheet sheet = sxssfWorkbook.createSheet("Sheet" + (i + 1));

				// Excel坐标
				int x = 0;
				int y = 0;

				// 设置工作表列名对应的成员变量名列表
				List<String> fieldNameList = null;
				// 列名不为空
				if (null != columnNameMapLists.get(i)) {

					// 获取工作表列名
					Map<String, String> columnNameMap = columnNameMapLists.get(i);
					Set<String> fieldNames = columnNameMap.keySet();

					// 设置工作表列名
					fieldNameList = new LinkedList<String>();
					Row row = sheet.createRow(y);
					for (String fieldName : fieldNames) {
						// 设置列名
						Cell cell = row.createCell(x);
						cellStyle = sxssfWorkbook.createCellStyle();
						// 单元格水平居中orizontalAlignment.CENTER
						cellStyle.setAlignment(CENTER);
						// 单元格垂直居中
						cellStyle.setVerticalAlignment(CENTER);
					
						cell.setCellStyle(setColumnNameStyle(sxssfWorkbook, excelExtName));
						cell.setCellValue(columnNameMap.get(fieldName));
						//设置列宽
						setColumnWidth(sheet, x);
						fieldNameList.add(fieldName);
						x++;
					}
					y++;

				}

				// 内容不为空
				if (null != contentLists && i < contentLists.size()) {

					// 设置内容
					for (T object : contentLists.get(i)) {
						// 忽略空对象
						if (null != object) {
							x = 0;
							Row row = sheet.createRow(y);

							for (String fieldName : fieldNameList) {
								Object attribute = null;

								if (object instanceof Map) {
									// 获取Map中的值
									attribute = ((Map<?, ?>) object).get(fieldName);
								} else {
									// 获取对象中的值
									Field field = object.getClass().getDeclaredField(fieldName);
									field.setAccessible(true);
									attribute = field.get(object);
								}

								Object value = getFormatValue(object, attribute);
								Cell cell = row.createCell(x);
								cell.setCellStyle(cellStyle);

								if (value instanceof String) {
									cell.setCellValue((String) value);
								} else if (value instanceof Double) {
									cell.setCellValue((Double) value);
								}
								x++;
							}

						}
						y++;
						// 导出上限
						if (y > ExcelUtil.getMaxRoW(excelExtName)) {
							break;
						}
					}

				}

			}
		

			// 写出Excel
			sxssfWorkbook.write(outputStream);
			// 关闭输出流
			if (null != outputStream) {
				outputStream.flush();
				outputStream.close();
				sxssfWorkbook.dispose();
			}
		} catch (Exception e) {
			e.printStackTrace();

			// 关闭输出流
			if (null != outputStream) {
				outputStream.flush();
				outputStream.close();
				sxssfWorkbook.dispose();
				//删除无效文件
				if (null != file) {
					file.delete();
					excelPath=null;
				}
			}
		
			throw new Exception(e);
		}
		return excelPath;
	}
	
	
	//----------------------导入辅助方法---------------------------
	private static Object getValueFromExcel(Cell cell){
		//DateUtil.isCellDateFormatt
		Object value = null;
		if (cell != null) {
			//value = cell.toString();
			  switch (cell.getCellType()) {     
			  case Cell.CELL_TYPE_STRING: // 字符串     
				  value = cell.getStringCellValue(); 
				  break;     
			  case Cell.CELL_TYPE_NUMERIC: // 数字类型 
			  //TODO 这里可能会有问题
				  if (DateUtil.isCellDateFormatted(cell)) {  //日期
					  value =	cell.getDateCellValue();	
				  } else {
			/*	  if (HSSFDateUtil.isCellDateFormatted(cell)) {  //日期
					  value =	cell.getDateCellValue();	
				  } else {*/
					  
//					  value = cell.getNumericCellValue(); //纯数字  
					  value = NUMBER_DATA_FORMAT.format(cell.getNumericCellValue()); //纯数字会最终解析为String,此做法无法完全兼容有小数点的数字
				  }               
				  	break;     
			  case Cell.CELL_TYPE_BLANK: // 空值     
				  value = null;
				  break;     
			  case Cell.CELL_TYPE_BOOLEAN: // Boolean     
				  value = cell.getBooleanCellValue();             
				  break;     
			  case Cell.CELL_TYPE_FORMULA: // 公式     
				  value = cell.getCellFormula();   
				  break;     
			  case Cell.CELL_TYPE_ERROR: // 故障     
//				  value = null;    
				  break;     
			  default:     
//				  value = null;       
				  break;     
			  }     
		}
		return value;
	}
	
	
	//----------------------导出辅助方法---------------------------
	/**
	 * 数据处理
	 * 
	 * @param object
	 *            对象JavaBean 或者 Map
	 * @param attribute
	 *            属性值
	 * @return 处理后的值
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 */
	private static Object getFormatValue(Object object, Object attribute)
			throws IllegalArgumentException, IllegalAccessException {

		if (null != attribute) {
			// 日期格式处理
			SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-hh-mm  hh:MM:ss");
			if (attribute instanceof Date) {
				return dateFormat.format(attribute);
				// 数字类型
			} else if (attribute instanceof Number) {
				if (attribute instanceof Double) {
					return attribute;
				}
				return Double.parseDouble(attribute.toString());
			}

		}
		return (null != attribute) ? (attribute.toString()) : "";
	}

	/**
	 * 表头样式调整
	 * 
	 * @param cellStyle
	 *            样式
	 * @return
	 * @throws Exception
	 */
	private static CellStyle setColumnNameStyle(Workbook workBook, String excelExtName) throws Exception {
		CellStyle cellStyle = null;
//		if (excelExtName.equals(XLS)) {
//			cellStyle = workBook.createCellStyle();
//			cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);  //水平居中
//			cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);  //垂直剧中
//			HSSFFont font = (HSSFFont) workBook.createFont();
//			font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);// 粗体显示
//			cellStyle.setFont(font);
//		} else if (excelExtName.equals(XLSX)) {
//			cellStyle = workBook.createCellStyle();
//			cellStyle.setAlignment(XSSFCellStyle.ALIGN_CENTER);  //水平居中
//			cellStyle.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);  //垂直居中
//			XSSFFont font = (XSSFFont) workBook.createFont();
//			font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);// 粗体显示
//			cellStyle.setFont(font);
//		} else {
//			throw new Exception("excel文件后缀名错误！");
//		}
		if (excelExtName.equals(XLS)||excelExtName.equals(XLSX)) {
			cellStyle = workBook.createCellStyle();
			// 单元格水平居中
			cellStyle.setAlignment(CENTER);
			// 单元格垂直居中
			cellStyle.setVerticalAlignment(CENTER);
			Font font =  workBook.createFont();
			// 粗体显示
			font.setBold(true);
			cellStyle.setFont(font);
		} else {
			throw new Exception("excel文件后缀名错误！");
		}

		return cellStyle;
	}
	
	/**
	 * 设置表格的宽度
	 * @param sheet
	 * @param columnIndex
	 */
	private static void setColumnWidth(Sheet sheet, int columnIndex){
		//sheet.autoSizeColumn(x, true);   //自动宽度
		Integer with = 30;                 //设置列宽，30个字符宽
		sheet.setColumnWidth(columnIndex, with * 256);  
	}
	
	
	
	
	//---------------------------------------------------------
	//样式调整示例
	//
	// // 生成一个样式
	// HSSFCellStyle style = workbook.createCellStyle();
	// // 设置这些样式
	// style.setAlignment(HSSFCellStyle.ALIGN_CENTER);//水平居中
	// style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//垂直居中
	//
	// // 背景色
	// style.setFillForegroundColor(HSSFColor.YELLOW.index);
	// style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
	// style.setFillBackgroundColor(HSSFColor.YELLOW.index);
	//
	// // 设置边框
	// style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
	// style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
	// style.setBorderRight(HSSFCellStyle.BORDER_THIN);
	// style.setBorderTop(HSSFCellStyle.BORDER_THIN);
	// // 自动换行
	// style.setWrapText(true);
	//
	// // 生成一个字体
	// HSSFFont font = workbook.createFont();
	// font.setFontHeightInPoints((short) 10);
	// font.setColor(HSSFColor.RED.index);
	// font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
	// font.setFontName("宋体");
	//
	// // 把字体 应用到当前样式
	// style.setFont(font);
	//
	// //style设置好后，为cell设置样式
	// cell.setCellStyle(style)//cell为已有的单元格
	//
	//
	//--------------------------------------------------------------
	//  ---------------------网络IO流导出样例：
	//
	//	// 每日数据导出
	//		@RequestMapping(value = "expReportsDailyExcel", method = RequestMethod.GET)
	//*****	public void expReportsDailyExcel(HttpServletResponse response, String access_token) throws Exception {
	//
	//			try {
	//				// 权限校验（临时使用）
	//				// 获取操作用户
	//				User user = userService.getUserInSession();
	//				MgRole role = mgUserService.getRoleByUserId(user.getId().toString());
	//				String orgId = role.getOrgId().toString();
	//				// 有权限才执行
	//				if (orgId.equals("0")) {
	//
	//					// 内容列表
	//					List<List<Map<String, Object>>> contentLists = new ArrayList<>();
	//
	//					List<Map<String, Object>> checkinStaffList = eventService.expReportsDaily();
	//					contentLists.add(checkinStaffList);
	//
	//					// 传输类型
	//***** 			response.setContentType("application/ms-excel; charset=UTF-8");
	//
	//					String excelExtName = "xlsx";
	//					String fileName = new SimpleDateFormat("yyyy_MM_dd").format(new Date());
	//*****				response.addHeader("Content-Disposition",
	//							"attachment;filename=daily_report_" + fileName + "." + excelExtName);
	//
	//					// 表头列表
	//					LinkedHashMap<String, String> columnNameMap = ExcelHead.getExcelHead("reportsDailyHead");
	//					List<LinkedHashMap<String, String>> columnNameMapLists = new LinkedList<>();
	//					columnNameMapLists.add(columnNameMap);
	//
	//******			ExcelUtil.exportExcel(response.getOutputStream(), null, null, excelExtName, null, columnNameMapLists,
	//							contentLists);
	//
	//				}
	//
	//			} catch (Exception e) {
	//				// TODO: handle exception
	//				log.info("-----------导出Reports日报失败");
	//				e.printStackTrace();
	//			}
	//		}
	//	}
	//----------------------服务器本地存储，并压缩后发送给前端样例
	//
	// 每日数据导出
	//	@RequestMapping(value = "expReportsExcel", method = RequestMethod.GET)
	//**public ResponseEntity<byte[]> expReportsExcel(HttpServletRequest request,HttpServletResponse response, String access_token) throws Exception {
	//
	//***   String path = request.getSession().getServletContext().getRealPath("/");
	//		File file = null;
	//		try {
	//			// 获取操作用户
	//			User user = userService.getUserInSession();
	////			MgRole role = mgUserService.getRoleByUserId(user.getId().toString());
	////			String orgId = role.getOrgId().toString();
	//			String orgId = "0";
	//			// 如果不属于同一组，直接返回
	//			if (orgId.equals("0")) {
	//
	//				// 内容列表
	//				List<List<Map<String, Object>>> contentLists = new ArrayList<>();
	//
	//				List<Map<String, Object>> checkinStaffList = eventService.expReports();
	//				contentLists.add(checkinStaffList);
	//
	//				// 文件名设置
	//				String excelExtName = "xlsx";
	//				String fileName = new SimpleDateFormat("yyyy_MM_dd").format(new Date());
	//				fileName = "all_event_data_" + fileName; 
	//				//Excel输出路径 根目录的data/excelData
	//				path = path+"WEB-INF/classes/excelData/";
	//			
	//
	//				// Excel表头列表
	//				LinkedHashMap<String, String> columnNameMap = ExcelHead.getExcelHead("collectHead");
	//				List<LinkedHashMap<String, String>> columnNameMapLists = new LinkedList<>();
	//				columnNameMapLists.add(columnNameMap);
	//
	//****			ExcelUtil.exportExcel(null, path, fileName, excelExtName, null, columnNameMapLists,
	//						contentLists);
	//				
	//				// 获取Excel文件
	//****			file = new File(path+fileName+"."+excelExtName);
	//				// Zip压缩对象列表
	//****			List<File> files = new ArrayList<File>();
	//****			files.add(file);
	//				// Zip压缩文件输出全路径
	//****			String zipAllPath = path+fileName+".zip";
	//				// 压缩文件
	//****			ZipUtil.zipFile(zipAllPath,files);
	//				// 获取压缩文件
	//****			file = new File(path + fileName+".zip");	
	//				
	//				// 传输类型
	//****			response.setContentType("application/octet-stream; charset=UTF-8");
	//				// 传输头信息
	//****			response.addHeader("Content-Disposition",
	//						"attachment;filename="+fileName+ ".zip");	
	//			}
	//
	//		} catch (Exception e) {
	//			// TODO: handle exception
	//			e.printStackTrace();
	//		}
	//		//传输文件
	//****	return new ResponseEntity<byte[]>(org.apache.commons.io.FileUtils.readFileToByteArray(file), HttpStatus.CREATED);
	//
	//	}
	//---------------------导入数据
	//@RequestMapping(value = "test", method = RequestMethod.POST)
	//	public @ResponseBody Response test( MultipartFile file) {
	//		
	//		Response response = new Response();
	//		try {
	//			ExcelUtil.showExcelContent(file.getOriginalFilename(), file.getInputStream());
	//		} catch (Exception e) {
	//		
	//			e.printStackTrace();
	//		}
	//		
	//		return response.success();
	//	}
	// --------------------------------------------------------------
	public static void main(String[] args) throws Exception {
		// 读取Excel
/*		 String fliePath ="H:\\hong.xlsx";
		 ExcelUtil.showExcelContent(fliePath,null);
		 List<LinkedHashMap<String, String>> columnNameMapLists = new
		 LinkedList<LinkedHashMap<String, String>>();
		 LinkedHashMap<String, String> columnNameMap = new
		 LinkedHashMap<String, String>();
		 columnNameMap.put("a", "A");
		 columnNameMap.put("b", "B");
		 columnNameMap.put("c", "C");
		 columnNameMap.put("d", null);
		 columnNameMap.put("e", "E");
		 columnNameMap.put("f", "F");
		 columnNameMap.put("g", "G");
		 columnNameMapLists.add(columnNameMap);
		 columnNameMapLists.add(columnNameMap);
		 List<List<LinkedHashMap<String, Object>>> contentListsM = new
		 ArrayList<List<LinkedHashMap<String,Object>>>();
		 List<LinkedHashMap<String, Object>> l = new
		 ArrayList<LinkedHashMap<String,Object>>();
		 LinkedHashMap<String, Object> columnNameMapM = new
		 LinkedHashMap<String, Object>();
		 columnNameMapM.put("a", 1);
		 columnNameMapM.put("b", "a1");
		 columnNameMapM.put("c", null);
		 columnNameMapM.put("d", 1l);
		 columnNameMapM.put("e", new Date());
		 columnNameMapM.put("f", true);
		 columnNameMapM.put("g", 4.5f);
		 l.add(columnNameMapM);
		 l.add(null);
		 l.add(columnNameMapM);
		 contentListsM.add(l);
		 ExcelUtil.exportExcel(null, null, "XXX", "xlsx", null,
		 columnNameMapLists, contentListsM);*/

		// ----------------SimpleExample 2------------------------
		/* List<String> sheetNames = new LinkedList<String>();
		 sheetNames.add("测试1");
		 sheetNames.add("测试2");
		
		 List<LinkedHashMap<String, String>> columnNameMapLists = new
		 LinkedList<LinkedHashMap<String, String>>();
		 LinkedHashMap<String, String> columnNameMap = new
		 LinkedHashMap<String,String>();
		 columnNameMap.put("a", "A");
		 columnNameMap.put("b", "B");
		 columnNameMap.put("c", "C");
		 columnNameMap.put("d", null);
		 columnNameMap.put("e", "E");
		 columnNameMap.put("f", "F");
		 columnNameMap.put("g", "G");
		 columnNameMapLists.add(columnNameMap);
		 columnNameMapLists.add(columnNameMap);
		
		 List<List<A>> contentLists = new LinkedList<List<A>>();
		 List<A> contentList = new LinkedList<A>();
		 contentList.add(new A(1, "a1", null, 1l, new Date(), true, 3.4f));
		 contentList.add(new A(1, "a2", null, 1l, new Date(), true, 4.5f));
		 contentList.add(null);
		 contentList.add(new A(1, "a4", null, 1l, new Date(), true, 5.7f));
		 contentLists.add(contentList);
		 contentLists.add(contentList);
		
		 ExcelUtil.exportExcel(null, null, null, null,XLS,columnNameMapLists, contentLists);*/
		
		// ----------------SimpleExample 3------------------------
//				(成员变量名 -表头)的映射
//				 List<LinkedHashMap<String, String>> columnNameMapLists = new
//				 LinkedList<LinkedHashMap<String, String>>();
//				 LinkedHashMap<String, String> columnNameMap = new
//				 LinkedHashMap<String, String>();
//				 columnNameMap.put("a", "A");
//				 columnNameMap.put("b", "B");
//				 columnNameMap.put("c", "C");
//				 columnNameMap.put("d", null);
//				 columnNameMap.put("e", "E");
//				 columnNameMap.put("f", "F");
//				 columnNameMap.put("g", "G");
//				 columnNameMapLists.add(columnNameMap);
//				 columnNameMapLists.add(columnNameMap);
//				
//				 List<List<LinkedHashMap<String, Object>>> contentListsM = new
//				 ArrayList<List<LinkedHashMap<String,Object>>>();
//				 List<LinkedHashMap<String, Object>> l = new
//				 ArrayList<LinkedHashMap<String,Object>>();
//				 LinkedHashMap<String, Object> columnNameMapM = new
//				 LinkedHashMap<String, Object>();
//				 columnNameMapM.put("a", 1);
//				 columnNameMapM.put("b", "a1");
//				 columnNameMapM.put("c", null);
//				 columnNameMapM.put("d", 1l);
//				 columnNameMapM.put("e", new Date());
//				 columnNameMapM.put("f", true);
//				 columnNameMapM.put("g", 4.5f);
//				 l.add(columnNameMapM);
//				 l.add(null);
//				 l.add(columnNameMapM);
//				 contentListsM.add(l);
//				 ExcelUtil.exportExcelForHugeData("C:\\Users\\linru\\Desktop", "XXXX", columnNameMapLists, contentListsM);
	}

}
